package com.xmjs.baselibrary.utils.album;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import androidx.core.content.FileProvider;

import android.util.Log;

import com.xmjs.baselibrary.utils.PermissionUtils;
import com.zxy.tiny.Tiny;

import java.io.File;
import java.io.IOException;

import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;

/**
 * 调用系统相机/相册/裁剪功能的工具类
 */
public class AlbumUtils {

    public final static int TAKE_PHOTO = 10001;
    public final static int OPEN_ALBUM = 10002;
    public final static int CROP_IMAGE = 10003;

    private Uri outputUri;//裁剪照片保存地址
    private String imagePath;//打开相册选择照片的路径
    private String mPhotoPath;//相机拍照后的存储路径
    private boolean isClickCamera;//是否是拍照裁剪
    public int aspectX = 16;
    public int aspectY = 9;
    public int outputX = 960;
    public int outputY = 540;
    public boolean isCrop = true;//拍照/选择图片后，是否启用裁剪
    PermissionUtils permission;

    public AlbumUtils() {
        permission = new PermissionUtils();
    }

    /**
     * 设置裁剪宽高比例
     *
     * @param aspectX
     * @param aspectY
     */
    public void setProportion(int aspectX, int aspectY) {
        this.aspectX = aspectX;
        this.aspectY = aspectY;
    }

    /**
     * 设置图片输出大小
     *
     * @param outputX
     * @param outputY
     */
    public void setOutputSize(int outputX, int outputY) {
        this.outputX = outputX;
        this.outputY = outputY;
    }

    /**
     * 设置拍照/选择图库后，是否进行裁剪
     *
     * @param isCrop
     */
    public void setCrop(boolean isCrop) {
        this.isCrop = isCrop;
    }

    /**
     * 请求权限
     *
     * @param activity
     * @param action
     */
    private void requestPermission(Activity activity, Action action) {
        permission.requestPermission(activity, new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CAMERA
        }, action, "需要存储权限和摄像头权限才能正常使用应用");
    }

    /**
     * 请求权限的回调处理
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults) {
        permission.onRequestPermissionsResult(activity, requestCode, permissions, grantResults);
    }

    /**
     * 拍照/图库/裁剪的回调
     *
     * @param activity
     * @param requestCode
     * @param resultCode
     * @param data
     * @param consumer
     */
    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data, Consumer<ImageRes> consumer) {
        //去设置里面手动开启权限后仍然要持续检查是否已经开启所有权限
        permission.onActivityResult(activity, requestCode, resultCode, data);

        if (requestCode == TAKE_PHOTO && resultCode == Activity.RESULT_OK) {//拍照回调
            if (isCrop) {
                cropPhoto(activity, mPhotoPath);//裁剪图片
            } else {
                compressData(mPhotoPath, consumer);//压缩数据并传递回调
            }

        } else if (requestCode == OPEN_ALBUM && resultCode == Activity.RESULT_OK) {//图库回调
            if (Build.VERSION.SDK_INT >= 19) {
                //4.4及以上系统使用这个方法处理图片
                handleImageOnKitKat(activity, data, consumer);
            } else {
                //4.4以下系统使用这个方法处理图片
                handleImageBeforeKitKat(activity, data, consumer);
            }

        } else if (requestCode == CROP_IMAGE && resultCode == Activity.RESULT_OK) {//裁剪回调
            ImageRes entity = new ImageRes();
            String path = "";
            Bitmap bitmap = null;
            try {
                if (isClickCamera) {
                    bitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(outputUri));
                    path = outputUri.getPath();
                } else {
                    bitmap = BitmapFactory.decodeFile(outputUri.getPath());
                    path = outputUri.getPath();
                }
                entity.bitmap = bitmap;//原位图
                entity.path = path;//原图路径

                //图片压缩
                Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
                Tiny.getInstance().source(entity.path).asFile().withOptions(options)
                        .compress((isSuccess, bmp, outfile, t) -> {
                            entity.path = outfile;//压缩后的图片路径
                            try {
                                consumer.accept(entity);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 调用相机拍照
     */
    public void takePhoto(Activity activity) {
        //先去检查并请求权限
        requestPermission(activity, () -> {
            isClickCamera = true;
            Uri imageUri = null;
            // 创建File对象，用于存储拍照后的图片
            File outputImage = new File(activity.getExternalCacheDir(), "output_image.jpg");
            mPhotoPath = outputImage.getPath();
            try {
                if (outputImage.exists()) {
                    outputImage.delete();
                }
                outputImage.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                //Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri
                //参数二:fileprovider绝对路径 com.dyb.testcamerademo：项目包名
                imageUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", outputImage);
            } else {
                imageUri = Uri.fromFile(outputImage);
            }
            // 启动相机程序
            Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            activity.startActivityForResult(intent, TAKE_PHOTO);
        });
    }

    /**
     * 打开相册
     */
    public void openAlbum(Activity activity) {
        //先去检查并请求权限
        requestPermission(activity, () -> {
            isClickCamera = false;
            Intent intent = new Intent();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_PICK);
            } else {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            }
            intent.setType("image/*");
            activity.startActivityForResult(intent, OPEN_ALBUM);
        });
    }

    /**
     * 裁剪图片
     */
    private void cropPhoto(Activity activity, String path) {
        File file = new File(path);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        Uri imageUri;
        File outputImage = new File(activity.getExternalCacheDir(), System.currentTimeMillis() + "crop_image.jpg");
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //通过FileProvider创建一个content类型的Uri
            imageUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", file);
            outputUri = Uri.fromFile(outputImage);
        } else {
            imageUri = Uri.fromFile(file);
            outputUri = Uri.fromFile(outputImage);
        }
        intent.setDataAndType(imageUri, "image/*");
        intent.putExtra("crop", "true");
        //设置宽高比例
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        //设置裁剪图片宽高
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        intent.putExtra("scale", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", false);
        activity.startActivityForResult(intent, CROP_IMAGE);
    }

    /**
     * 4.4及以上系统使用这个方法处理图片 相册图片返回的不再是真实的Uri,而是分装过的Uri
     *
     * @param activity
     * @param data
     * @param consumer
     */
    @TargetApi(19)
    private void handleImageOnKitKat(Activity activity, Intent data, Consumer<ImageRes> consumer) {
        imagePath = null;
        Uri uri = data.getData();
        Log.d("TAG", "handleImageOnKitKat: uri is " + uri);
        if (DocumentsContract.isDocumentUri(activity, uri)) {
            // 如果是document类型的Uri，则通过document id处理
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1]; // 解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(activity, contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是content类型的Uri，则使用普通方式处理
            imagePath = getImagePath(activity, uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            // 如果是file类型的Uri，直接获取图片路径即可
            imagePath = uri.getPath();
        }

        if (isCrop) {
            //进入裁剪页面
            cropPhoto(activity, imagePath);
        } else {
            compressData(imagePath, consumer);
        }

    }

    /**
     * 4.4以下系统使用这个方法处理图片
     *
     * @param activity
     * @param data
     * @param consumer
     */
    private void handleImageBeforeKitKat(Activity activity, Intent data, Consumer<ImageRes> consumer) {
        Uri uri = data.getData();
        imagePath = getImagePath(activity, uri, null);
        if (isCrop) {
            //进入裁剪页面
            cropPhoto(activity, imagePath);
        } else {
            compressData(imagePath, consumer);
        }
    }

    /**
     * 压缩数据并传递回调
     *
     * @param path
     * @param consumer
     */
    private void compressData(String path, Consumer<ImageRes> consumer) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        ImageRes entity = new ImageRes();
        entity.bitmap = bitmap;//原位图
        entity.path = path;//原图路径

        //图片压缩
        Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
        options.size = 1024;//最大1M
        Tiny.getInstance().source(entity.path).asFile().withOptions(options)
                .compress((isSuccess, bmp, outfile, t) -> {
                    entity.path = outfile;//压缩后的图片路径
                    try {
                        consumer.accept(entity);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
    }

    /**
     * 获取图片路径
     *
     * @param activity
     * @param uri
     * @param selection
     * @return
     */
    private String getImagePath(Activity activity, Uri uri, String selection) {
        String path = null;
        // 通过Uri和selection来获取真实的图片路径
        Cursor cursor = activity.getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

}
